<template>
  <div
    class="lyric_control_container"
    :class="[bgImageClass]"
    :style="
      isShow
        ? {}
        : {
            maxWidth: '560px',
            margin: '0 auto',
          }
    "
  >
    <ul ref="lyricControlRef" class="lyric_control" :class="[isShow ? 'scrollbar_none' : '']">
      <div style="height: 50%"></div>
      <li
        :style="`text-align: ${textAlign}`"
        class="li"
        :class="[item.selected ? 'active' : '', `${isShow ? '' : 'hover-bg-gray-200'}`]"
        v-for="(item, index) in scrollLyric"
        :data-index="index"
        :key="index"
        @click="moveLyricVerticalCenter(index)"
      >
        <span
          class="cursor-pointer"
          :style="{ ...zhutiTitleStyle, lineHeight: textStyle.lineHeight }"
          v-if="index === 0"
          >{{ item.text }}</span
        >
        <span
          :class="[`text-shadow-${textShadow}`, 'cursor-pointer']"
          v-else
          :style="item.selected ? activeFontSize : textStyle"
          >{{ item.text }}</span
        >
      </li>
      <div style="height: 50%"></div>
    </ul>
    <div
      style="
        position: absolute;
        width: 60px;
        height: 100%;
        background: transparent;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
      "
      :style="`${textAlign === 'right' ? 'left:0' : 'right:0'}`"
      v-if="!isShow"
    >
      <button @click="handlePreLyricRow">&#128405;</button>
      <button @click="handleNextLyricRow">&#128071;</button>
    </div>
  </div>
</template>
<script>
import "./jcScrollLyric.css";

export default {
  name: "JcScrollLyric",
  props: {
    bgImageClass: {
      type: String,
      default: "bgjb",
    },
    zhutiTitleStyle: {
      type: Object,
      default: {
        fontSize: "1.5rem",
        color: "#fff",
      },
    },
    textShadow: {
      type: Number,
      default: 0,
    },
    textStyle: {
      type: Object,
      default: {
        fontSize: "1rem",
        color: "#fff",
      },
    },
    lyric: {
      type: String,
      default: "",
    },
    textAlign: {
      type: String,
      default: "center",
    },
    isShow: {
      type: Boolean,
      default: false,
    },
    scrollProgress: {
      type: [String, Number],
      default: 0,
    },
  },
  data() {
    return {
      scrollLyric: [],
    };
  },
  computed: {
    activeFontSize() {
      return { ...this.textStyle, fontSize: `${parseInt(this.textStyle.fontSize) + 10}px` };
    },
    selectedIndex() {
      if (this.scrollLyric.length) {
        return (
          this.scrollLyric.map((item, index) => ({ selected: item.selected, index })).filter((item) => item.selected)[0]
            .index || 0
        );
      }
      return 0;
    },
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.createScrollLyric();
      this.scrollTo(0);
      this.$nextTick(() => {
        const self = this;
        this.$refs.lyricControlRef.addEventListener("scroll", function () {
          const progress = Math.round((this.scrollTop / (this.scrollHeight - this.clientHeight)) * 1000) / 1000;

          self.$emit("scroll", progress);
        });

        this.viewPortIntersection(this.$refs.lyricControlRef, {
          callBack: (entries, observer) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                const cindex = parseInt(entry.target.dataset.index);
                this.$emit("selectedChange", cindex);
                // 这个代码具有副作用
                this.scrollLyric = this.scrollLyric.map((item, index) => {
                  item.selected = index === cindex;
                  return item;
                });
              }
            });
          },
        });
      });
    },
    // 生成歌词数组
    createScrollLyric() {
      if (this.lyric === "") {
        return [];
      }
      this.scrollLyric = this.lyric
        .split("\n")
        .filter((i) => i !== "")
        .map((item, index) => ({
          text: item,
          index,
          selected: false,
        }));
    },
    /**
     * 视口相交监听
     * container 父元素的element
     * * */
    viewPortIntersection(container, options) {
      console.log("container-->", container);
      const observer = new IntersectionObserver(
        (entries, observer) => {
          if (options.callBack) {
            options.callBack(entries, observer);
          }
        },
        { root: container, rootMargin: "-50% 0px -50% 0px", threshold: 0.0 }
      );
      for (let i = 0; i < container.children.length; i++) {
        const el = container.children[i];
        if (el.nodeName !== "DIV") {
          observer.observe(el);
        }
      }
    },
    scrollTo(top, isAnm = false) {
      const option = { top };
      if (isAnm) {
        option.behavior = "smooth";
      }
      this.$refs.lyricControlRef.scrollTo(option);
    },
    moveLyricVerticalCenter(index) {
      console.log("parseInt(this.textStyle.lineHeight)-->", parseInt(this.textStyle.lineHeight));
      const lineHeight = parseInt(this.textStyle.lineHeight) < 24 ? 24 : parseInt(this.textStyle.lineHeight);
      const top = index * lineHeight + lineHeight - 1;
      console.log(top);
      this.scrollTo(top);
    },
    /**
     * 选中下一条歌词行
     * * */
    handleNextLyricRow() {
      if (this.selectedIndex >= this.scrollLyric.length) {
        return;
      }
      const nextIndex = this.selectedIndex + 1;
      this.moveLyricVerticalCenter(nextIndex);
    },
    /**
     * 选中上一条歌词行
     * * */
    handlePreLyricRow() {
      if (this.selectedIndex <= 0) {
        return;
      }
      const preIndex = this.selectedIndex - 1;
      this.moveLyricVerticalCenter(preIndex);
    },
  },
  watch: {
    lyric() {
      this.init();
    },
    scrollProgress() {
      if (this.isShow) {
        const showViewProgress =
          (this.$refs.lyricControlRef.scrollHeight - this.$refs.lyricControlRef.clientHeight) * this.scrollProgress;
        this.scrollTo(showViewProgress, true);
      }
    },
  },
};
</script>
<style>
.scrollbar_none::-webkit-scrollbar {
  display: none !important;
}
.cursor-pointer {
  cursor: pointer;
}
.hover-bg-gray-200:hover {
  background-color: rgba(255, 255, 255, 0.3);
}
</style>
